package logic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import com.jme.math.Vector3f;

public class SpawnLocation {
	
	protected static final float SPAWN_DIST = 20f;
	protected static final int MAX_SPAWNS = 27;
	protected static final int SPAWNS_PER_SIDE = 3;
	
	protected List<Vector3f> spawns, usedSpawns;
	protected Random r;
	protected Vector3f spawnLoc;
	protected float orientationAngle;
	
	public SpawnLocation(float orientationAngle) {
		this.orientationAngle = orientationAngle;
		
		spawns = new ArrayList<Vector3f>();
		usedSpawns = new ArrayList<Vector3f>();
		r = new Random();
	}
	
	public SpawnLocation(Vector3f spawnLoc, float orientationAngle) {
		this(orientationAngle);
		this.spawnLoc = spawnLoc;
		assert(spawnLoc != null);
		generateSpawns(spawnLoc);
	}
	
	public Vector3f getRandomSpawn() {
		if(spawns.isEmpty()) return null;
		assert(spawnLoc != null);
		if(spawns.size() == usedSpawns.size()) {
			Collections.shuffle(spawns, r);
			usedSpawns.clear();
		}
		int newIndex = usedSpawns.size();
		Vector3f newSpawnLoc = spawns.get(newIndex);
		usedSpawns.add(newSpawnLoc);
		assert(newSpawnLoc != null);
		return newSpawnLoc;
	}
	
	protected void generateSpawns(Vector3f spawnLoc) {
		assert(spawnLoc != null);
		float init = SPAWNS_PER_SIDE * SPAWN_DIST / 2f;
		Vector3f currentLoc = spawnLoc.subtract(init, init, init);
		Vector3f XDIR = Vector3f.UNIT_X.mult(SPAWN_DIST);
		Vector3f YDIR = Vector3f.UNIT_Y.mult(SPAWN_DIST);
		Vector3f ZDIR = Vector3f.UNIT_Z.mult(SPAWN_DIST);
		
		for(int i = 0; i < SPAWNS_PER_SIDE; i++) {
			Vector3f oldXLoc = currentLoc.clone();
			
			for(int j = 0; j < SPAWNS_PER_SIDE; j++) {
				Vector3f oldZLoc = currentLoc.clone();
				
				for(int k = 0; k < SPAWNS_PER_SIDE; k++) {
					spawns.add(currentLoc.clone());
					currentLoc.addLocal(YDIR);
				}
				currentLoc = oldZLoc.add(ZDIR);
			}
			currentLoc = oldXLoc.add(XDIR);
		}
		assert(spawns.size() == 27);
		usedSpawns.clear();
		Collections.shuffle(spawns, r);
	}
	
	public float getOrientationAngle() { return orientationAngle; }
	
	public Vector3f getLocation() { return spawnLoc; }
	
	public List<Vector3f> getSpawns() { return spawns; }
}